﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BoolanElement.RedoUndo;
using Windows.Data.Xml.Dom;
using Windows.Storage;
using System.Xml.Linq;
using BoolanElement.Storage;
using Windows.UI.Xaml.Media.Imaging;
using System.IO;
using BoolanSlide.FileManager;
using System.Threading;
using BoolanSlide.FileStruct;
using Configuration;
using Windows.UI.Xaml.Media;
using BoolanSlide.BooCommon;
using BoolanSlide.Document.Storage;
using BoolanSlide.Document.Format.Helper;

namespace BoolanElement
{
    public delegate bool RedoUndoForThumbNails(SlideOperation slideOperation, int[] ShowIndex);

    public class BooDocument:IDisposable
    {
        /// <summary>
        /// 临时解决RedoUndo异步问题
        /// </summary>
        public ThumbNailsHelper thumbNailsHelper;

        /// <summary>
        /// Slide 列表
        /// </summary>
        public List<BooSlide> Slides;

        /// <summary>
        /// 文件描述信息
        /// </summary>
        public BPTFileInformation FileInformation;

        public BooDocument()
        {
            FileInformation = new BPTFileInformation();
            Slides = new List<BooSlide>();
        }

        /// <summary>
        /// 根据Slide对象增加新的Slide
        /// </summary>
        /// <param name="slide"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public async Task<BooSlide> AddSlide(BooSlide slide, int index)
        {
            XDocument doc = null;
            BooSlide newSlide = null;
            StorageFolder folder = null;
            StorageFolder imageFolder = null;
            await StorageLock.WaitSignal.WaitAsync();
            doc = slide.Save();
            newSlide = BooSlideHelper.GenerateSlide(doc);
            newSlide.AttachToDocument(this);
            folder = await BooUtility.GetFolderFromDocumentFolderAsync(BooDocumentHelper.ImageTmpFolder);
            imageFolder = await BooUtility.GetFolderFromDocumentFolderAsync(BooDocumentHelper.ImageFolder);

            await ImageManager.CopyImage(folder, imageFolder, newSlide.BackgroundImagePath);
            foreach (var item in newSlide.Elements)
            {
                if (item is BooTextBoxElement)
                {
                    ((BooTextBoxElement)item).IsFromTemplate = true;
                }
                else if (item is BooPictureElement)
                {
                    await ImageManager.CopyImage(folder, imageFolder, (item as BooPictureElement).filePath);
                }
            }
            Slides.Insert(index, newSlide);
            StorageLock.WaitSignal.Release();
            return newSlide;
        }

        /// <summary>
        /// 移除索引为Index的Slide
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool RemoveSlide(int index)
        {
            if (index > Slides.Count - 1 || index < 0)
                return false;
            Slides.RemoveAt(index);
            return true;
        }
        /// <summary>
        /// 在索引为index处插入Slide
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool InsertSlide(int index, BooSlide slide = null)
        {
            if (index > Slides.Count || index < 0)
                return false;
            Slides.Insert(index, slide);
            return true;
        }

        /// <summary>
        /// 从from移动slide至to处
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public bool MoveSlide(int from, int to)
        {
            if (from == to)
                return false;
            else
            {
                BooSlide slide = Slides.ElementAt(from);
                Slides.RemoveAt(from);
                Slides.Insert(to, slide);
                return true;
            }
        }

        /// <summary>
        /// 剪切索引为Index的Slide
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool CutSlide(int index)
        {
            CopySlide(index);
            RemoveSlide(index);
            return true;
        }

        /// <summary>
        /// 复制索引为index的Slide
        /// </summary>
        /// <param name="index"></param>
        public void CopySlide(int index)
        {

            Configuration.GlobalVariable.CopyedSlide = Slides.ElementAt(index);
        }

        /// <summary>
        /// 粘贴Slide至Index处
        /// </summary>
        /// <param name="CopyedSlide"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public BooSlide PasteSlide(BooSlide CopyedSlide, int index)
        {
            BooSlide ret = null;
            if (CopyedSlide != null)
            {
                BooSlide slide = BooSlideHelper.GenerateSlide(CopyedSlide.Save());
                slide.AttachToDocument(this);
                Slides.Insert(index, slide);
                ret = slide;
                StorageLock.WaitSignal.Release();
                return ret;
            }
            return ret;
        }

        /// <summary>
        /// 获取索引为index的Slide的深拷贝
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public BooSlide GetSlideCopy(int index)
        {
            BooSlide copyedSlide = BooSlideHelper.GenerateSlide(Slides.ElementAt(index).Save());
            copyedSlide.AttachToDocument(this);
            return copyedSlide;
        }

        /// <summary>
        /// 总结文档
        /// </summary>
        /// <returns></returns>
        public String Summary()
        {
            XDocument document = XDocument.Parse("<BoolanPPT></BoolanPPT>");
            document.Root.Add(new XElement("Count") { Value = Slides.Count.ToString() });
            document.Root.Add(new XElement("StorageName") { Value = FileInformation.StorageName });
            document.Root.Add(new XElement("Resolution") { Value = ((int)FileInformation.Resolution).ToString() });
            document.Root.Add(new XElement("CreateTime") { Value = FileInformation.CreateTime.ToString() });
            document.Root.Add(new XElement("ThemeGUID") { Value = FileInformation.ThemeGuid.ToString() });
            return document.ToString();
        }

        /// <summary>
        /// 销毁对象
        /// </summary>
        public void Dispose()
        {
            foreach (BooSlide slide in Slides)
            {
                slide.Dispose();
            }
        }
    }
}
